package com.ruoyi.form.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.form.base.Def;
import com.ruoyi.form.base.StringUtils;
import com.ruoyi.form.domain.*;
import com.ruoyi.form.mapper.AxFieldMapper;
import com.ruoyi.form.service.IAxModelFieldService;
import com.ruoyi.form.service.IAxFieldService;
import com.ruoyi.form.service.IAxModelService;
import com.ruoyi.form.service.IAxUploadTypeService;
import com.ruoyi.system.service.ISysDictDataService;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 【请填写功能名称】Service业务层处理
 *
 * @author LZF
 * @date
 */
@Service
public class AxFieldServiceImpl extends ServiceImpl<AxFieldMapper, AxField> implements IAxFieldService {

    @Autowired
    private AxFieldMapper axFieldMapper;
    @Autowired
    private IAxModelFieldService axModelFieldService;
    @Autowired
    private IAxUploadTypeService axUploadTypeService;
    @Autowired
    private IAxModelService axModelService;
    @Autowired
    private ISysDictDataService sysDictDataService;

    /**
     * 查询【请填写功能名称】
     *
     * @param id 【请填写功能名称】主键
     * @return 【请填写功能名称】
     */
    @Override
    public AxField selectAxFieldById(String id) {
        return axFieldMapper.selectAxFieldById(id);
    }

    /**
     * 查询【请填写功能名称】列表
     *
     * @param axField 【请填写功能名称】
     * @return 【请填写功能名称】
     */
    @Override
    public List<AxField> selectAxFieldList(AxField axField) {
        return axFieldMapper.selectAxFieldList(axField);
    }

    /**
     * 新增【请填写功能名称】
     *
     * @param axField 【请填写功能名称】
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor=Exception.class)
    public int insertAxField(AxField axField) {
        if(axField.getFormWidth() == null){
            axField.setFormWidth(200L);
        }
        axField.setCreateTime(DateUtils.getNowDate());
        int rows = axFieldMapper.insert(axField);
        if (rows > 0) {
            AxModelField axModelField = new AxModelField();
            axModelField.setFieldId(axField.getId());
            axModelField.setFilterType(getTypeByField(axField));
            axModelField.setName(axField.getBasicName());
            axModelField.setShowFlag("1");
            axModelField.setModelId("root_all");
            if (StringUtils.isNotEmpty(axField.getParentId())) {
                axModelField.setParentId(axField.getParentId());
            }
            axModelField.setSortNum(axField.getSortNum());
            axModelField.setFilterSortNum(axField.getSortNum());
            axModelField.setFormSortnum(axField.getSortNum());
            rows = axModelFieldService.insertAxModelField(axModelField);
        }
        return rows;
    }

    /**
     * 修改【请填写功能名称】 字段原属性修改，涉及到所有关联布局的页面属性都要修改，相应的数据也需要修改，这一点
     * 需要用户深刻理解，由于涉及面太广，此操作需谨慎，目前为了不把需求复杂扩大化，只是最简单化处理，只要修改了基础属性，那么页面布局要重新配置，至于数据
     * 需要用户手动去处理，至于是否删除，由用户选择
     *
     * @param axField 【请填写功能名称】
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor=Exception.class)
    public int updateAxField(AxField axField) {
        axField.setUpdateTime(DateUtils.getNowDate());
        int rows = axFieldMapper.updateAxField(axField);
        if (rows <= 0) {
            return rows;
        }
        AxModelField axModelFieldFilter = new AxModelField();
        axModelFieldFilter.setFieldId(axField.getId());
        QueryWrapper<AxModelField> frontGridQueryWrapper = new QueryWrapper<>();
        frontGridQueryWrapper.eq("field_id", axField.getId());
        boolean res = axModelFieldService.remove(frontGridQueryWrapper);
        if (!res) {
            return -1;
        }
        AxModelField axModelField = new AxModelField();
        axModelField.setFieldId(axField.getId());
        axModelField.setFilterType(getTypeByField(axField));
        axModelField.setName(axField.getBasicName());
        axModelField.setShowFlag("1");
        axModelField.setModelId("root_all");
        if (StringUtils.isNotEmpty(axField.getParentId())) {
            axModelField.setParentId(axField.getParentId());
        }
        axModelField.setSortNum(axField.getSortNum());
        axModelField.setFilterSortNum(axField.getSortNum());
        axModelField.setFormSortnum(axField.getSortNum());
        axModelField.setUpdateTime(DateUtils.getNowDate());
        rows = axModelFieldService.insertAxModelField(axModelField);
        return rows;
    }

    /**
     * 批量删除【请填写功能名称】
     *
     * @param ids 需要删除的【请填写功能名称】主键
     * @return 结果
     */
    @Override
    public int deleteAxFieldByIds(String[] ids) {
        return axFieldMapper.deleteAxFieldByIds(ids);
    }

    /**
     * 删除【请填写功能名称】信息
     *
     * @param id 【请填写功能名称】主键
     * @return 结果
     */
    @Override
    public int deleteAxFieldById(String id) {
        return axFieldMapper.deleteAxFieldById(id);
    }

    /*-----------------------------------------------------------------------------------------------------------------------*/
    /**
     * 判断是否不需要编码的静态filed code
     * @param code 原始代码
     * @return boolean
     */
    @Override
    public boolean isStaticCode(String code) {
        return code.equalsIgnoreCase(Def.id) || code.equalsIgnoreCase(Def.code)
                || code.equalsIgnoreCase(Def.name) || code.equalsIgnoreCase(Def.sortNum)
                || code.equalsIgnoreCase(Def.delFlag) || code.equalsIgnoreCase(Def.createUser)
                || code.equalsIgnoreCase(Def.updateUser) || code.equalsIgnoreCase(Def.createTime)
                || code.equalsIgnoreCase(Def.tplTableId) || code.equalsIgnoreCase(Def.rootId)
                || code.equalsIgnoreCase(Def.version) || code.equalsIgnoreCase(Def.createUserName);
    }
    /**
     * 获取代码
     * @return 代码
     */
    @Override
    public String getBasicCode() {
        String code = StringUtils.letterCode(8);
        AxField axField = new AxField();
        axField.setBasicCode(code);
        List<AxField> list = axFieldMapper.selectAxFieldList(axField);
        if (list != null && list.size() > 0) {
            boolean flag = true;
            while (flag) {
                code = StringUtils.letterCode(8);
                axField.setBasicCode(code);
                list = axFieldMapper.selectAxFieldList(axField);
                if (!(list != null && list.size() > 0)) {
                    flag = false;
                }
            }
        }
        return code.toUpperCase();
    }
    /**
     * 获取排序最大值
     * @return 代码
     */
    @Override
    public Integer getMaxSortNum() {
        Integer sortNum = 1;
        QueryWrapper<AxField> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("max(sort_num) as sortNum");
        List<Map<String, Object>> axFields = axFieldMapper.selectMaps(queryWrapper);
        if (axFields != null && axFields.size() > 0) {
            Map<String, Object> map = axFields.get(0);
            if (map != null && map.get("sortNum") != null) {
                sortNum += StringUtils.toInteger(map.get("sortNum"));
            }
        }
        return sortNum;
    }
    /**
     * 获取排序最大值
     * @param bo  AxField 实体
     * @return {@link List<AxField>}
     */
    @Override
    public List<AxField> queryRefAttributelistForModel(AxField bo) {
        return axFieldMapper.queryRefAttributelistForModel(bo);
    }
    /**
     * 查询引用属性（选择引用属性时）
     * @param bo AxField
     * @return {@link List<AxField>}
     */
    @Override
    public List<AxField> querySelectRefAttributelist(AxField bo) {
        List<AxField> list = axFieldMapper.querySelectRefAttributelist(bo);
        List<String> fieldIds = list.stream().map(bean->bean.getId()).collect(Collectors.toList());
        List<Map<String,Object>> modelList= axModelFieldService.selectFieldAccTemp(fieldIds);

        list.stream().forEach(element -> {
            //填充最终代码信息
            if(StringUtils.isNotEmpty(element.getBasicCode())){
                element.setFinalBasicCode(getPropertyName(element));
            }
            //去掉重复的name
            Set<String> modelNameSet=new LinkedHashSet<>();
            //填充模型信息
            if(CollectionUtils.isNotEmpty(modelList)){
                for(Map<String,Object> model:modelList){
                    if(element.getId().equals(model.get("field_id"))&& ObjectUtils.isNotEmpty(model.get("name"))) {
                        modelNameSet.add(model.get("name")+"");
                    }
                }
            }
            for(String name:modelNameSet) {
                element.setAssTemplates(
                        StringUtils.isEmpty(element.getAssTemplates())?name:element.getAssTemplates()+","+name
                );
            }
        });
        return list;
    }
    /**
     * 查询引用属性（选择引用属性时）
     * @param field AxField
     * @return {@link List<  AxField  >}
     */
    @Override
    public String getPropertyName(AxField field) {
        if (null == field || StringUtils.isEmpty(field.getBasicCode())) {
            return "";
        }
        String code = field.getBasicCode().toUpperCase();
        if (isStaticCode(code)) {
            return code.toUpperCase();
        }
        if (StringUtils.isNotBlank(field.getFormDictType())) {
            String dictId = field.getFormDictType();
            return Def.PC_ + code + Def._D_ + dictId.toUpperCase();
        } else {
            String javatype = field.getBasicJavaType();
            if ("string".equalsIgnoreCase(javatype)) {
                return Def.PS_ + code;
            } else if ("date".equalsIgnoreCase(javatype)||"datetime".equalsIgnoreCase(javatype)) {
                return Def.PD_ + code;
            } else if ("double".equalsIgnoreCase(javatype)||"int".equalsIgnoreCase(javatype)) {
                return Def.PN_ + code;
            }
        }
        return code;
    }
    /**
     * 保存引用属性
     * @param bo 业务实体
     * @return {@link Boolean}
     */
    @Override
    public Boolean insertRefBo(AxField bo) {
        QueryWrapper<AxField> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", bo.getRefIds());
        List<AxField> list = axFieldMapper.selectList(queryWrapper);
        List<AxModelField> axModelFields = new ArrayList<>();
        List<AxModel> childTableList = null;
        for (int i = 0; i < list.size(); i++) {
            AxField axField = list.get(i);
            AxModelField axModelField = new AxModelField();
            axModelField.setFieldId(axField.getId());
            axModelField.setFieldCode(axField.getBasicCode());
            String type = this.getTypeByField(axField);
            //  设置筛选项默认值
            axModelField.setFilterType(type);
            if ("date_range".equals(type)) {
                axModelField.setFormItemWidth(210L);
            } else {
                axModelField.setFormItemWidth(150L);
            }
            axModelField.setLabelWidth(StringUtils.isEmpty(axField.getBasicName())?40L: axField.getBasicName().length()*16L);
            axModelField.setFieldCode(axField.getBasicCode());
            axModelField.setName(axField.getBasicName());
            axModelField.setShowFlag("1");
            axModelField.setModelId(bo.getModelId());
            axModelField.setSortNum(axField.getSortNum());
            axModelField.setFilterSortNum(axField.getSortNum());
            axModelField.setFormSortnum(axField.getSortNum());
            axModelField.setAttachFlag("0");
            if(StringUtils.isNotEmpty(bo.getConfigFieldType())) {
                if ("filter".equals(bo.getConfigFieldType())) {
                    axModelField.setFilterPosition("1");
                } else if ("table".equals(bo.getConfigFieldType())) {
                    axModelField.setShowFlag("0");
                }
            }

            axModelFields.add(axModelField);
        }
        axModelFieldService.saveBatch(axModelFields);
        return true;
    }

    /**
     * 查询模型引用属性(表单显示设计器用)
     * @param axField
     * @return {@link List<  Element >}
     */
    @Override
    public List<Element> emlist(AxField axField) {
        List<AxField> list = this.queryRefAttributelistForModel(axField);
        List<Element> elements = new ArrayList<>();
        if (list != null && list.size() > 0) {
            for (AxField b : list) {
                Element element = new Element();
                element.setFieldId(b.getId());
                element.setModelId(b.getModelId());
                element.setParentId(b.getParentId());
                element.setBasicCode(getPropertyName(b));
                element.setLabel(b.getBasicName());
                element.setSpan(24);
                JSONObject style = new JSONObject();
                style.put("width", "100%");
                element.setStyle(style);
                if ("input".equals(b.getFormTypeName())) {
                    element.setTag("el-input");
                    element.setTagIcon("input");
                } else if ("textarea".equals(b.getFormTypeName())) {
                    element.setTag("el-input");
                    element.setTagIcon("textarea");
                } else if ("selectsingle".equals(b.getFormTypeName())
                        || "selectmulti".equals(b.getFormTypeName())
                        || "tags".equals(b.getFormTypeName())) {
                    element.setTag("el-select");
                    element.setTagIcon("select");
                    element.setPlaceholder("请选择");
                } else if ("date".equals(b.getFormTypeName())) {
                    element.setTag("el-date-picker");
                    element.setTagIcon("date");
                    element.setPlaceholder("请选择日期");
                } else if ("datetime".equals(b.getFormTypeName())) {
                    element.setTag("el-time-picker");
                    element.setTagIcon("time");
                    element.setPlaceholder("请选择时间");
                } else if ("radio".equals(b.getFormTypeName())) {
                    element.setTag("el-radio-group");
                    element.setTagIcon("radio");
                    element.setOptions(Element.newOptionList(null));
                } else if ("checkbox".equals(b.getFormTypeName())) {
                    element.setTag("el-checkbox-group");
                    element.setTagIcon("checkbox");
                    element.setOptions(Element.newOptionList(null));
                } else if ("upload".equals(b.getFormTypeName())) {
                    element.setTag("el-button");
                    element.setTagIcon("button");
                    element.setIcon("el-icon-upload");
                    element.setType("primary");
                    element.setSize("medium");
                    element.setStyle(null);
                } else if ("spinner".equals(b.getFormTypeName())) {
                    element.setTag("el-slider");
                    element.setTagIcon("slider");
                } else {
                    element.setTag("el-input");
                    element.setTagIcon("input");
                }
                if ("true".equals(b.getDataExtend())) {//复杂属性
                    element.setTag("el-checkbox-group");
                    element.setTagIcon("checkbox");
                    element.setOptions(Element.newOptionList("1"));
                }
                elements.add(element);
            }
        }
        return elements;
    }
    /**
     * 查询模型引用属性(表单显示设计器用)
     * @param axField
     * @return FieldLayout
     */
    @Override
    public FieldLayout layoutList(AxField axField) {
        JSONObject formData = axField.getFormData();
        JSONObject retData = new JSONObject();
        FieldLayout fieldLayout = new FieldLayout();
        List<AxField> list = this.queryRefAttributelist(axField);
        List<AxField> groups = list.stream().filter(b -> b.getLayoutGroupName() != null).collect(Collectors.toList());
        List<AxField> groupOuts = list.stream().filter(b -> b.getLayoutGroupName() == null).distinct().collect(Collectors.toList());
        if (groups != null && groups.size() > 0) {
            List<String> layoutGroupNames = groups.stream().map(AxField::getLayoutGroupName).distinct().collect(Collectors.toList());
            List<GroupLayout> groupLayouts = new ArrayList<>();
            for (String groupName : layoutGroupNames) {
                GroupLayout groupLayout = new GroupLayout();
                List<Element> elements = new ArrayList<>();
                groupLayout.setComponentName(groupName);
                List<AxField> childs = list.stream().filter(b -> groupName.equals(b.getLayoutGroupName())).collect(Collectors.toList());
                if (childs != null && childs.size() > 0) {
                    for (AxField field : childs) {
                        Element element = new Element();
                        element.setBasicCode(getPropertyName(field));
                        element.setLabel(field.getBasicName());
                        element.setSpan(field.getLayoutColSpan());
                        JSONObject style = new JSONObject();
                        style.put("width", "100%");
                        element.setStyle(style);
                        element.setFieldId(field.getId());
                        element.setModelId(field.getModelId());
                        element.setParentId(field.getParentId());
                        element.setIsDesign(field.getIsDesign());
                        //只读
                        element.setIsReadOnly(field.getIsReadOnly());
                        //必填
                        element.setJsRequired(field.getJsRequired());
                        if ("input".equals(field.getFormTypeName())) {
                            element.setTag("el-input");
                            element.setTagIcon("input");
                        } else if ("textarea".equals(field.getFormTypeName())) {
                            element.setTag("el-input");
                            element.setTagIcon("textarea");
                        } else if ("selectsingle".equals(field.getFormTypeName())
                                || "selectmulti".equals(field.getFormTypeName())
                                || "tags".equals(field.getFormTypeName())) {
                            element.setTag("el-select");
                            element.setTagIcon("select");
                            element.setPlaceholder("请选择");
                        } else if ("date".equals(field.getFormTypeName())) {
                            element.setTag("el-date-picker");
                            element.setTagIcon("date");
                            element.setPlaceholder("请选择日期");
                        } else if ("datetime".equals(field.getFormTypeName())) {
                            element.setTag("el-time-picker");
                            element.setTagIcon("time");
                            element.setPlaceholder("请选择时间");
                        } else if ("radio".equals(field.getFormTypeName())) {
                            element.setTag("el-radio-group");
                            element.setTagIcon("radio");
                            element.setOptions(Element.newOptionList(null));
                        } else if ("checkbox".equals(field.getFormTypeName())) {
                            element.setTag("el-checkbox-group");
                            element.setTagIcon("checkbox");
                            element.setOptions(Element.newOptionList(null));
                        } else if ("upload".equals(field.getFormTypeName())) {
                            element.setTag("el-button");
                            element.setTagIcon("button");
                            element.setIcon("el-icon-upload");
                            element.setType("primary");
                            element.setSize("medium");
                            element.setStyle(null);
                            AxUploadType type =  axUploadTypeService.selectAxUploadTypeById(field.getUploadTypeId());
                            if (type != null){
                                String exts = calcExts(type.getExts());
                                element.setExts(exts);
                                element.setUploadTypeId(type.getId());
                            }
                        } else if ("spinner".equals(field.getFormTypeName())) {
                            element.setTag("el-slider");
                            element.setTagIcon("slider");
                        } else {
                            element.setTag("el-input");
                            element.setTagIcon("input");
                        }
                        if ("true".equals(field.getDataExtend())) {//复杂属性
                            element.setTag("el-checkbox-group");
                            element.setTagIcon("checkbox");
                            //获取复杂属性的信息
                            QueryWrapper<AxField> qw = new QueryWrapper<>();
                            qw.eq("parent_id",field.getId());
                            qw.orderByAsc("sort_num");
                            List<AxField> fzList = axFieldMapper.selectList(qw);
                            //modified by lzf, 复杂属性中的上传属性，增加后缀名校验
                            if (null != fzList) {
                                for (AxField fz : fzList) {
                                    if ("upload".equals(fz.getFormTypeName())) {
                                        AxUploadType fzType =  axUploadTypeService.selectAxUploadTypeById(field.getUploadTypeId());
                                        if (fzType != null){
                                            String exts = calcExts(fzType.getExts());
                                            fz.setExts(exts);
                                        }
                                    }
                                }
                            }
                            element.setFuzaList(fzList);
                            element.setOptions(Element.newOptionList("1"));
                            element.setDataExtend(true);
                        }
                        if (StringUtils.isNotEmpty(field.getFormDictType())) {
                            SysDictData sysDictData = new SysDictData();
                            sysDictData.setDictType(field.getFormDictType());
                            List<SysDictData> sysDictDataList = sysDictDataService.getDictDataTree(sysDictData);
                            element.setDictList(sysDictDataList);
                        }
                        element.setBasicJavaType(field.getBasicJavaType());
                        element.setFormTypeName(field.getFormTypeName());
                        element.setDefaultValue(field.getDefaultValue());
                        element.setIsReadOnly(field.getIsReadOnly());
                        elements.add(element);
                    }
                }
                groupLayout.setChildren(elements);
                groupLayouts.add(groupLayout);
            }
            fieldLayout.setGroupLayouts(groupLayouts);
        } else {
            fieldLayout.setGroupLayouts(null);
        }
        if (groupOuts != null && groupOuts.size() > 0) {
            List<Element> elements = new ArrayList<>();
            for (AxField field : groupOuts) {
                Element element = new Element();
                element.setBasicCode(getPropertyName(field));
                element.setLabel(field.getBasicName());
                element.setSpan(field.getLayoutColSpan());
                JSONObject style = new JSONObject();
                style.put("width", "100%");
                element.setStyle(style);
                element.setFieldId(field.getId());
                element.setModelId(field.getModelId());
                element.setParentId(field.getParentId());
                element.setIsDesign(field.getIsDesign());
                element.setJsRequired(field.getJsRequired());
                if ("input".equals(field.getFormTypeName())) {
                    element.setTag("el-input");
                    element.setTagIcon("input");
                } else if ("textarea".equals(field.getFormTypeName())) {
                    element.setTag("el-input");
                    element.setTagIcon("textarea");
                } else if ("selectsingle".equals(field.getFormTypeName())
                        || "selectmulti".equals(field.getFormTypeName())
                        || "tags".equals(field.getFormTypeName())) {
                    element.setTag("el-select");
                    element.setTagIcon("select");
                    element.setPlaceholder("请选择");
                } else if ("date".equals(field.getFormTypeName())) {
                    element.setTag("el-date-picker");
                    element.setTagIcon("date");
                    element.setPlaceholder("请选择日期");
                } else if ("datetime".equals(field.getFormTypeName())) {
                    element.setTag("el-time-picker");
                    element.setTagIcon("time");
                    element.setPlaceholder("请选择时间");
                } else if ("radio".equals(field.getFormTypeName())) {
                    element.setTag("el-radio-group");
                    element.setTagIcon("radio");
                    element.setOptions(Element.newOptionList(null));
                } else if ("checkbox".equals(field.getFormTypeName())) {
                    element.setTag("el-checkbox-group");
                    element.setTagIcon("checkbox");
                    element.setOptions(Element.newOptionList(null));
                } else if ("upload".equals(field.getFormTypeName())) {
                    element.setTag("el-button");
                    element.setTagIcon("button");
                    element.setIcon("el-icon-upload");
                    element.setType("primary");
                    element.setSize("medium");
                    element.setStyle(null);

                    AxUploadType type =  axUploadTypeService.selectAxUploadTypeById(field.getUploadTypeId());
                    if (type != null){
                        String exts = type.getExts();
                        if (exts.contains("*.*") || StringUtils.isEmpty(exts)){
                            element.setExts(".*");
                        } else {
                            if (";".equals(exts.substring(exts.length() - 1))) exts = exts.substring(0,exts.length()-1);
                            exts = exts.replaceAll("\\*.",".");
                            exts = exts.replaceAll(";",",");
                            element.setExts(exts);
                        }
                        element.setUploadTypeId(type.getId());
                    }
                } else if ("spinner".equals(field.getFormTypeName())) {
                    element.setTag("el-slider");
                    element.setTagIcon("slider");
                } else {
                    element.setTag("el-input");
                    element.setTagIcon("input");
                }
                if ("true".equals(field.getDataExtend())) {//复杂属性
                    element.setTag("el-checkbox-group");
                    element.setTagIcon("checkbox");
                    element.setOptions(Element.newOptionList("1"));
                    element.setDataExtend(true);
                }
                if (StringUtils.isNotEmpty(field.getFormDictType())) {
                    SysDictData sysDictData = new SysDictData();
                    sysDictData.setDictType(field.getFormDictType());
                    List<SysDictData> sysDictDataList = sysDictDataService.getDictDataTree(sysDictData);
                    element.setDictList(sysDictDataList);
                }
                element.setBasicJavaType(field.getBasicJavaType());
                element.setFormTypeName(field.getFormTypeName());
                element.setDefaultValue(field.getDefaultValue());
                element.setIsReadOnly(field.getIsReadOnly());
                elements.add(element);
            }
            fieldLayout.setGroupOutLayouts(elements);
        } else {
            fieldLayout.setGroupOutLayouts(null);
        }
        if (formData != null) {
            fieldLayout.setRetData(retData);
        }
        AxModel model = axModelService.selectAxModelById(axField.getModelId());
        if (model != null) {
            fieldLayout.setFormSize(model.getFormSize());
            fieldLayout.setLabelPosition(model.getLabelPosition());
            fieldLayout.setLabelWidth(model.getLabelWidth());
        }
        return fieldLayout;
    }
    /**
     * 查询引用属性
     * @param bo 筛选项
     * @return {@link List<   AxField  >}
     */
    @Override
    public List<AxField> queryRefAttributelist(AxField bo) {
        return axFieldMapper.queryRefAttributelist(bo);
    }
    @Override
    public List<AxField> findFields(String tplId) {
        //从gird表查询模型字段对应关系
        QueryWrapper<AxModelField> qw = new QueryWrapper<>();
        qw.in("model_id", tplId);
        qw.in("attach_flag","0");
        List<AxModelField> axModelFieldList = axModelFieldService.list(qw);
        List<String> fieldIds= axModelFieldList.stream().map(AxModelField::getFieldId).collect(Collectors.toList());
        if(fieldIds.size()==0){
            return Lists.newArrayList();
        }
        List<AxField> fields = axFieldMapper.selectBatchIds(fieldIds);
        //根据字段id返回字段列表
        return fields;
    }
    /**
     * 查询子属性列表
     */
    @Override
    public List<AxField> queryChildList(String parentId) {
        AxField bo=new AxField();
        bo.setParentId(parentId);
        LambdaQueryWrapper<AxField> lqw = buildQueryWrapper(bo);
        return axFieldMapper.selectList(lqw);
    }
    @Override
    public Boolean saveLayout(FieldLayout fieldLayout, List<AxModelField> axModelFields) {
        List<GroupLayout> groupLayouts = fieldLayout.getGroupLayouts();
        List<Element> groupOutLayouts = fieldLayout.getGroupOutLayouts();
        List<AxModelField> axModelFieldList = new ArrayList<>();
        if (groupLayouts != null && groupLayouts.size() > 0) {
            for (int i = 0; i < groupLayouts.size(); i++) {
                GroupLayout groupLayout = groupLayouts.get(i);
                String groupName = groupLayout.getComponentName();
                List<Element> childrens = groupLayout.getChildren();
                for (int j = 0; j < childrens.size(); j++) {
                    Element element = childrens.get(j);
                    List<AxModelField> BussModelFieldList = axModelFields.stream().filter(b -> b.getFieldId().equals(element.getFieldId())).collect(Collectors.toList());
                    if (BussModelFieldList != null && BussModelFieldList.size() > 0) {
                        AxModelField frontGrid = BussModelFieldList.get(0);
                        frontGrid.setLayoutGroupName(groupName);
                        frontGrid.setLayoutColSpan(element.getSpan());
                        frontGrid.setLayoutGroupSortNum(i);
                        frontGrid.setLayoutFieldSortNum(j);
                        axModelFieldList.add(frontGrid);
                    }
                }
            }
        }
        if (groupOutLayouts != null && groupOutLayouts.size() > 0) {
            for (int i = 0; i < groupOutLayouts.size(); i++) {
                Element element = groupOutLayouts.get(i);
                List<AxModelField> BussModelFieldList = axModelFields.stream().filter(b -> b.getFieldId().equals(element.getFieldId())).collect(Collectors.toList());
                if (BussModelFieldList != null && BussModelFieldList.size() > 0) {
                    AxModelField frontGrid = BussModelFieldList.get(0);
                    frontGrid.setLayoutColSpan(element.getSpan());
                    frontGrid.setLayoutFieldSortNum(i);
                    axModelFieldList.add(frontGrid);
                }
            }
        }
        List<String> layoutIds = axModelFieldList.stream().map(AxModelField::getId).collect(Collectors.toList());
        List<AxModelField> oldLayouts = axModelFields.stream().filter(b -> !layoutIds.contains(b.getId()) && b.getLayoutFieldSortNum() != null).collect(Collectors.toList());
        if (oldLayouts != null && oldLayouts.size() > 0) {
            for (AxModelField bussModelField : oldLayouts) {
                bussModelField.setLayoutGroupName(null);
                bussModelField.setLayoutColSpan(null);
                bussModelField.setLayoutGroupSortNum(null);
                bussModelField.setLayoutFieldSortNum(null);
                axModelFieldList.add(bussModelField);
            }
        }
        axModelFieldService.saveOrUpdateBatch(axModelFieldList);
        return true;
    }
    @Override
    public void delRefBo(AxField bo) {
        QueryWrapper<AxField> queryWrapper = new QueryWrapper();
        queryWrapper.in("id", bo.getRefIds());
        List<AxField> bussFields = axFieldMapper.selectList(queryWrapper);
        if (bussFields != null && bussFields.size() > 0) {
            QueryWrapper<AxModelField> gridQueryWrapper = new QueryWrapper<>();
            gridQueryWrapper.in("field_id", bo.getRefIds());
            gridQueryWrapper.eq("model_id", bo.getModelId());
            gridQueryWrapper.eq("show_flag", '1');
            gridQueryWrapper.isNull("filter_position");
            List<AxModelField> bussModelFields = axModelFieldService.list(gridQueryWrapper);
            List<String> ids = bussModelFields.stream().map(AxModelField::getId).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(ids)){
                axModelFieldService.removeBatchByIds(ids);
            }
        }
    }
    /**
     * 获取属性的表单元素类型 作为筛选项值
     * @param axField AxField
     * @return 表单元素类型
     */
    private String getTypeByField(AxField axField) {
        String formType = axField.getFormTypeName();
        String javaType = axField.getBasicJavaType();

        if (StringUtils.isNotEmpty(axField.getFormDictType())){
            return "select";
        } else{
            if ("input".equals(formType)){
                if ("int".equalsIgnoreCase(javaType) || "double".equalsIgnoreCase(javaType)){
                    return "number_range";
                } else if ("date".equalsIgnoreCase(javaType) || "datetime".equalsIgnoreCase(javaType)){
                    return "date_range";
                } else{
                    return "input";
                }
            } else if ("date".equalsIgnoreCase(formType) || "datetime".equalsIgnoreCase(formType)){
                return "date_range";
            } else {
                return "input";
            }
        }
    }
    private String calcExts(String exts) {
        if (StringUtils.isEmpty(exts)) {
            return null;
        }
        String _exts = new String(exts);
        if (_exts.contains("*.*") || StringUtils.isEmpty(_exts)){
            return ".*";
        }
        if (";".equals(_exts.substring(_exts.length() - 1))) {
            _exts = _exts.substring(0, _exts.length() - 1);
        }
        _exts = _exts.replaceAll("\\*.",".");
        _exts = _exts.replaceAll(";",",");
        return _exts;
    }
    private LambdaQueryWrapper<AxField> buildQueryWrapper(AxField bo) {
        LambdaQueryWrapper<AxField> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getId()), AxField::getId, bo.getId());
        lqw.eq(StringUtils.isNotBlank(bo.getCreateBy()), AxField::getCreateBy, bo.getCreateBy());
        lqw.eq(StringUtils.isNotBlank(bo.getRemark()), AxField::getRemark, bo.getRemark());
        lqw.eq(bo.getSortNum() != null, AxField::getSortNum, bo.getSortNum());
        lqw.eq(StringUtils.isNotBlank(bo.getUpdateBy()), AxField::getUpdateBy, bo.getUpdateBy());
        lqw.eq(StringUtils.isNotBlank(bo.getParentId()), AxField::getParentId, bo.getParentId());
        lqw.eq(StringUtils.isNotBlank(bo.getBasicCode()), AxField::getBasicCode, bo.getBasicCode());
        lqw.eq(StringUtils.isNotBlank(bo.getBasicJavaType()), AxField::getBasicJavaType, bo.getBasicJavaType());
        lqw.like(StringUtils.isNotBlank(bo.getBasicName()), AxField::getBasicName, bo.getBasicName());
        if ("ftrue".equals(bo.getDataExtend())) {
            lqw.ne(StringUtils.isNotBlank(bo.getDataExtend()), AxField::getDataExtend, "true");
        } else {
            lqw.eq(StringUtils.isNotBlank(bo.getDataExtend()), AxField::getDataExtend, bo.getDataExtend());
        }
        lqw.eq(StringUtils.isNotBlank(bo.getFormDictType()), AxField::getFormDictType, bo.getFormDictType());
        if(StringUtils.isNotBlank(bo.getFormTypeName())){
            if(bo.getFormTypeName().equals("datalist")){
                lqw.eq(AxField::getDataExtend, "true");
            }else{
                lqw.eq(AxField::getFormTypeName, bo.getFormTypeName());
            }
        }

        lqw.eq(StringUtils.isNotBlank(bo.getDefaultValue()), AxField::getDefaultValue, bo.getDefaultValue());
        lqw.eq(bo.getFormWidth() != null, AxField::getFormWidth, bo.getFormWidth());
        lqw.eq(StringUtils.isNotBlank(bo.getJsRequired()), AxField::getJsRequired, bo.getJsRequired());
        lqw.eq(StringUtils.isNotBlank(bo.getModelId()), AxField::getModelId, bo.getModelId());
        lqw.eq(StringUtils.isNotBlank(bo.getUploadTypeId()), AxField::getUploadTypeId, bo.getUploadTypeId());
        lqw.eq(StringUtils.isNotBlank(bo.getIsReadOnly()), AxField::getIsReadOnly, bo.getIsReadOnly());
        lqw.eq(StringUtils.isNotBlank(bo.getIsAddDelFlag()), AxField::getIsAddDelFlag, bo.getIsAddDelFlag());
        lqw.eq(StringUtils.isNotBlank(bo.getAutoCodeRuleStr()), AxField::getAutoCodeRuleStr, bo.getAutoCodeRuleStr());
        lqw.eq(StringUtils.isNotBlank(bo.getIsAutoCode()), AxField::getIsAutoCode, bo.getIsAutoCode());
        if(StringUtils.isNotBlank(bo.getAttributeType())) {
            lqw.eq(AxField::getAttributeType, bo.getAttributeType());
        }
        if(StringUtils.isNotEmpty(bo.getTemplateCode())) {
            lqw.exists("select 1 from ax_model_field where field_id=ax_field.id_ and model_id={0}",bo.getTemplateCode());
        }
        return lqw;
    }
}
